<?php 
include_once 'viper/autoloader.php';

class viper_server_proximityfinder {
public static $n = 100;     // number of users
public static $m = 50;      // number of features 
public static $k = 5;       // # of clusters
public static $f = 10;      // # of friends

private static function GetDist($a, $b) {
  $d = 0;
  for ($i = 0; $i < self::$m; $i++) {
    $d = $d + pow(($a['feature'.$i] - $b['feature'.$i]), 2);
  }
  return $d;
}

public static function FindFriends($clusters, $result) {
  $n = self::$n;
  $m = self::$m;
  $k = self::$k;
  $f = self::$f;
  
  // Cache the distances
  $dist = array();
  for ($i = 0; $i < $n; $i++) {
    $ar = array();
    for ($j = 0; $j < $n; $j++) {
      $ar[] = self::GetDist($result[$i], $result[$j]);
    }
    $dist[] = $ar;
  }
  
  //  Find the friends
  $friends = array();
  for ($idx = 0; $idx < $k; $idx++) {
    // Find the size of the cluster
    $csize = count($clusters[$idx]);
    
    for ($i = 0; $i < $csize; $i++) {
      $heap = new viper_server_DistHeap();
      $cur = $clusters[$idx][$i];
      $friends[$cur] = array();
      for ($j = 0; $j < $csize; $j++) {
        if ($i != $j) {
          $ar = array();
          $ar['dist'] = $dist[$cur][$clusters[$idx][$j]];
          $ar['idx'] = $clusters[$idx][$j];
          // var_dump($ar);
          $heap->insert($ar);
        }
      }
      // echo '<br />';
      // Extract the ten users who have the least distance
      for ($j = 0; $j < $f; $j++) {
        if ($heap->isEmpty()) {
          for (; $j < $f; $j++) {
            $friends[$cur][$j] = -1;
          }
        } else {
          $ar = $heap->top();
          // echo '  '.$ar['dist'];
          $friends[$cur][$j] = $ar['idx'];
          $heap->next();
        }
      }
      
      unset($heap);
    }  //End of loop for users in each cluster
  }  // End of loop for clusters
  
  return $friends;
}

}  // End of class viper_server_proximityfinder
?>